﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using SoarD.Pandora;
using UnityEditor;
using UnityEngine;

namespace SoarDEditor.Pandora.Window
{
    public partial class PdrWindow
    {
        public interface IDrawPanel
        {
            void DrawPanel();
        }
        public class PanelSet<T> : IEnumerable<KeyValuePair<string, BoxSet<T>>> where T : UnityEngine.Object
        {
            private Dictionary<string, BoxSet<T>> m_BoxSet;

            public PanelSet()
            {
                m_BoxSet = new Dictionary<string, BoxSet<T>>();
            }

            public void Add(string title, object key, T val)
            {
                if (!m_BoxSet.ContainsKey(title))
                {
                    m_BoxSet.Add(title, new BoxSet<T>());
                }
                m_BoxSet[title].Add(key, val);
            }

            public void Clear()
            {
                m_BoxSet.Clear();
            }

            public bool Contains(string key)
            {
                return m_BoxSet.ContainsKey(key);
            }

            public BoxSet<T> this[string key]
            {
                get { return m_BoxSet[key]; }
            }

            public int Count
            {
                get { return m_BoxSet.Count; }
            }

            IEnumerator<KeyValuePair<string, BoxSet<T>>> IEnumerable<KeyValuePair<string, BoxSet<T>>>.GetEnumerator()
            {
                return m_BoxSet.GetEnumerator();
            }

            public IEnumerator GetEnumerator()
            {
                return m_BoxSet.GetEnumerator();
            }
        }

        public class BoxSet<T> : IEnumerable<KeyValuePair<string, List<T>>> where T : UnityEngine.Object
        {
            private Dictionary<string, List<T>> m_ResultSet;

            public BoxSet()
            {
                m_ResultSet = new Dictionary<string, List<T>>();
            }

            public void Add(object obj, T val)
            {
                string key = obj.ToString();
                if (m_ResultSet.ContainsKey(key))
                {
                    if (!m_ResultSet[key].Contains(val))
                    {
                        m_ResultSet[key].Add(val);
                    }
                }
                else
                {
                    m_ResultSet.Add(key, new List<T> { val });
                }
            }

            public List<T> this[string key]
            {
                get { return m_ResultSet[key]; }
            }

            public int Count
            {
                get { return m_ResultSet.Count; }
            }

            public IEnumerator<KeyValuePair<string, List<T>>> GetEnumerator()
            {
                return m_ResultSet.GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return m_ResultSet.GetEnumerator();
            }
        }

        public static void DrawResultSet<T>(PanelSet<T> ResultSet, ref Vector2 ResultPanelScrollView) where T : UnityEngine.Object
        {
            GUILayout.BeginVertical();
            {
                ResultPanelScrollView = EditorGUILayout.BeginScrollView(ResultPanelScrollView);
                foreach (KeyValuePair<string, BoxSet<T>> resutSet in ResultSet)
                {
                    GUILayout.BeginVertical(); //内大框
                    {
                        GUILayout.BeginVertical();
                        {
                            EditorGUILayout.LabelField(resutSet.Key, EditorStyles.boldLabel);
                            GUILayout.BeginHorizontal("box");
                            {
                                GUILayout.Space(5);
                                foreach (var valList in resutSet.Value)
                                {
                                    GUILayout.BeginVertical(GUILayout.MaxWidth(400));
                                    EditorGUILayout.LabelField(string.Format("{0}: ({1})", valList.Key, valList.Value.Count), EditorStyles.boldLabel);
                                    GUILayout.BeginVertical("box");
                                    foreach (var val in valList.Value)
                                    {
                                        EditorGUILayout.ObjectField(val, typeof(T), true);
                                    }
                                    GUILayout.EndVertical();
                                    GUILayout.EndVertical();
                                }
                                GUILayout.Space(5);
                            }
                            GUILayout.EndHorizontal();
                        }
                        EditorGUILayout.EndVertical();
                    }
                    GUILayout.EndVertical();
                }

                EditorGUILayout.EndScrollView();
            }
            GUILayout.EndVertical();
        }

        public class NavFuncBase<T> : IDrawPanel where T : UnityEngine.Object
        {
            private List<string> m_NavTitles = new List<string>();
            private List<string> m_FixTitles = new List<string>();
            private List<Action> m_NavActions = new List<Action>();
            private List<Action> m_FixActions = new List<Action>();

            private StringBuilder logHandle = new StringBuilder();

            protected PanelSet<T> m_ResultSet = new PanelSet<T>();

            private Vector2 m_NavFuncScrollView;
            private Vector2 m_ResultPanelScrollView;

            protected void AddNavButton(string title, Action action)
            {
                m_NavTitles.Add(title);
                m_NavActions.Add(action);
            }

            protected void AddFixButton(string title, Action action)
            {
                m_FixTitles.Add(title);
                m_FixActions.Add(action);
            }

            protected void AddClearButton()
            {
                AddFixButton("Clear", Clear);
            }

            #region LogFile

            public void LogOpen()
            {
                logHandle.Length = 0;
            }

            public void LogAppend(string info, AssetObject obj, UnityEngine.Object item = null)
            {
                if (item)
                {
                    LogAppend(info, obj.name, item.name);
                }
                else
                {
                    LogAppend(info, obj.name);
                }
            }
            public void LogAppend(string info, UnityEngine.Object obj, UnityEngine.Object item = null)
            {
                if (item)
                {
                    LogAppend(info, obj.name, item.name);
                }
                else
                {
                    LogAppend(info, obj.name);
                }
            }

            public void LogAppend(string info, string objName, string itemName = null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(string.Format("[info]:{0}\t", info));
                sb.Append(string.Format("[预制]:{0}\t", objName));
                if (!string.IsNullOrEmpty(itemName))
                {
                    sb.Append(string.Format("[描述]:{0}\t", itemName));
                }
                LogAppend(sb.ToString());
            }

            public void LogAppend(string str)
            {
                logHandle.AppendLine(str);
            }

            public void WriteLog()
            {
                LogFile.WriteLog(ToString().Split('+')[1], logHandle.ToString());
            }
            #endregion

            #region Draw

            public void DrawPanel()
            {
                GUILayout.Space(5f);
                GUILayout.BeginHorizontal();
                {
                    if (m_NavTitles.Count > 0)
                    {
                        GUILayout.BeginVertical(GUILayout.MaxWidth(100));
                        {
                            GUILayout.BeginVertical(GUILayout.Height(m_Window.position.height - 100));
                            {
                                GUILayout.Space(5f);
                                EditorGUILayout.LabelField("检测工具", EditorStyles.boldLabel);
                                GUILayout.BeginVertical("box", GUILayout.Height(m_Window.position.height - 150));
                                {
                                    m_NavFuncScrollView = EditorGUILayout.BeginScrollView(m_NavFuncScrollView);
                                    {
                                        DrawNavButtons();
                                    }
                                    EditorGUILayout.EndScrollView();

                                }
                                EditorGUILayout.EndVertical();
                            }
                            GUILayout.EndVertical();
                        }
                        GUILayout.EndVertical();
                    }

                    if (m_FixTitles.Count > 0)
                    {
                        GUILayout.BeginVertical(GUILayout.MaxWidth(100));
                        {
                            GUILayout.BeginVertical(GUILayout.Height(m_Window.position.height - 100));
                            {
                                GUILayout.Space(5f);
                                EditorGUILayout.LabelField("修复工具", EditorStyles.boldLabel);
                                GUILayout.BeginVertical("box", GUILayout.Height(m_Window.position.height - 150));
                                {
                                    m_NavFuncScrollView = EditorGUILayout.BeginScrollView(m_NavFuncScrollView);
                                    {
                                        DrawFixButtons();
                                    }
                                    EditorGUILayout.EndScrollView();

                                }
                                EditorGUILayout.EndVertical();
                            }
                            GUILayout.EndVertical();
                        }
                        GUILayout.EndVertical();
                    }

                    DrawResultSet(m_ResultSet, ref m_ResultPanelScrollView);
                }
                GUILayout.EndHorizontal();
            }

            private void DrawNavButtons()
            {
                for (int i = 0; i < m_NavTitles.Count; i++)
                {
                    GUILayout.Space(5);
                    if (GUILayout.Button(m_NavTitles[i], GUILayout.Height(25)))
                    {
                        m_NavActions[i].Invoke();
                    }
                }
            }

            private void DrawFixButtons()
            {
                for (int i = 0; i < m_FixTitles.Count; i++)
                {
                    GUILayout.Space(5);
                    if (GUILayout.Button(m_FixTitles[i], GUILayout.Height(25)))
                    {
                        m_FixActions[i].Invoke();
                    }
                }
            }

            protected void Clear()
            {
                m_ResultSet.Clear();
                LogOpen();
            }
        }
        #endregion
    }
}
